package com.codebase.alicloud;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtils;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.ui.TextAnchor;
import org.jfree.data.category.DefaultCategoryDataset;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

public class JfreechartUtil {

    public static void main(String[] args) throws Exception {
        drawChart();
        //test();
    }


    public static void drawChart() throws IOException {
        // 创建数据集
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        dataset.addValue(70, "租户-1", "租户~1");
        dataset.addValue(20, "租户-2", "租户~2");
        dataset.addValue(30, "租户-3", "租户~3");
        dataset.addValue(40, "租户-4", "租户~4");


        //设置字体
        JFreeChart chart = ChartFactory.createBarChart(
                "供票系统-业务发生额报表", // 图表标题，使用中文
                "租户名称", // 域轴（X）标签，使用中文
                "总发生额", // 范围轴（Y）标签，使用中文
                dataset // 数据集
        );

        CategoryPlot plot = chart.getCategoryPlot();
        plot.setBackgroundPaint(Color.white);    //设置网格竖线颜色
        plot.setDomainGridlinePaint(Color.pink); //设置网格横线颜色
        plot.setRangeGridlinePaint(Color.pink);  //显示每个柱的数值，并修改该数值的字体属性

        chart.getTitle().setFont(new Font("宋体", Font.BOLD, 25));

        Font font =  new Font("宋体", Font.PLAIN, 14);
        chart.getLegend().setItemFont(font);  // 设置图例项字体

        plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
        plot.getDomainAxis().setTickLabelFont(font);  // 设置X轴 key字体
        plot.getDomainAxis().setLabelFont(font);    //设置x轴标题字体

        plot.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT);
        plot.getRangeAxis().setLabelFont(font); // 设置Y轴标题字体

        plot.getRenderer().setSeriesPaint(0, Color.RED);    // 设置第一个系列的颜色
        plot.getRenderer().setSeriesPaint(1, Color.BLUE);   // 设置第二个系列的颜色
        plot.getRenderer().setSeriesPaint(2, Color.GREEN);  // 设置第三个系列的颜色
        plot.getRenderer().setSeriesPaint(3, Color.ORANGE); // 设置第四个系列的颜色

        plot.getRenderer().setDefaultItemLabelFont(font);     //设置柱子上的数字字体及大小
        plot.getRenderer().setDefaultItemLabelsVisible(true);

        ChartUtils.saveChartAsPNG(new File("chart.png"), chart, 600, 400);

    }



    public static void test() throws Exception {

        // 查询每个月的用量
        Map<String, Double> monthlyUsage = new LinkedHashMap<>();
        //初始化monthlyUsage
        monthlyUsage.put("6月-1周", 148.00);
        monthlyUsage.put("6月-2周", 196.00);
        monthlyUsage.put("6月-3周", 223.00);
        monthlyUsage.put("6月-4周", 227.00 );
        monthlyUsage.put("7月-1周", 207.00);
        monthlyUsage.put("7月-2周", 201.00);
        monthlyUsage.put("7月-3周", 213.00);
        monthlyUsage.put("7月-4周", 139.00);
        monthlyUsage.put("8月-1周", 213.00 );
        monthlyUsage.put("8月-2周", 185.00 );


//
        Map<String, Double> monthlyUsage2 = new LinkedHashMap<>();
        //初始化monthlyUsage
        monthlyUsage2.put("6月-1周", 248.00);
        monthlyUsage2.put("6月-2周", 296.00);
        monthlyUsage2.put("6月-3周", 323.00);
        monthlyUsage2.put("6月-4周", 327.00);
        monthlyUsage2.put("7月-1周", 307.00);
        monthlyUsage2.put("7月-2周", 301.00);
        monthlyUsage2.put("7月-3周", 313.00);
        monthlyUsage2.put("7月-4周", 239.00);
        monthlyUsage2.put("8月-1周", 313.00 );
        monthlyUsage2.put("8月-2周", 285.00 );


        Map<String, Double> monthlyUsage3 = new LinkedHashMap<>();
        //初始化monthlyUsage
        monthlyUsage3.put("6月-1周", 396.00);
        monthlyUsage3.put("6月-2周", 492.00);
        monthlyUsage3.put("6月-3周", 546.00);
        monthlyUsage3.put("6月-4周", 554.00);
        monthlyUsage3.put("7月-1周", 514.00);
        monthlyUsage3.put("7月-2周", 502.00);
        monthlyUsage3.put("7月-3周", 526.00);
        monthlyUsage3.put("7月-4周", 378.00);
        monthlyUsage3.put("8月-1周", 526.00 );
        monthlyUsage3.put("8月-2周", 470.00 );


        DefaultCategoryDataset dataset2 = new DefaultCategoryDataset();
        for (Map.Entry<String, Double> entry : monthlyUsage3.entrySet()) {
            dataset2.addValue(entry.getValue(), "总量", entry.getKey());
        }
        // 创建折线图数据集
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (Map.Entry<String, Double> entry : monthlyUsage.entrySet()) {
            dataset.addValue(entry.getValue(), "FER", entry.getKey());
        }

        for (Map.Entry<String, Double> entry : monthlyUsage2.entrySet()) {
            dataset.addValue(entry.getValue(), "POCT", entry.getKey());
        }

        // 创建折线图
        JFreeChart chart = ChartFactory.createLineChart(
                "湖北妇幼保健院用量统计表", // 图表标题
                "时间",              // X轴标签
                "用量",               // Y轴标签
                dataset,               // 数据集
                PlotOrientation.VERTICAL, // 图表方向
                true,                  // 是否显示图例
                true,                  // 是否显示工具提示
                false                  // 是否显示URL
        );

// 创建折线图
        JFreeChart chart2 = ChartFactory.createLineChart(
                "湖北妇幼保健院总用量统计表", // 图表标题
                "时间",              // X轴标签
                "用量",               // Y轴标签
                dataset2,               // 数据集
                PlotOrientation.VERTICAL, // 图表方向
                true,                  // 是否显示图例
                true,                  // 是否显示工具提示
                false                  // 是否显示URL
        );
        // **正确设置字体**
        Font titleFont = new Font("宋体", Font.BOLD, 20);  // 不能直接实例化 Font，必须使用构造方法
        Font labelFont = new Font("宋体", Font.BOLD, 14 );
        chart.getTitle().setFont(titleFont);
        chart.getLegend().setItemFont(labelFont);

        chart2.getTitle().setFont(titleFont);
        chart2.getLegend().setItemFont(labelFont);
        // 获取图表的 Plot（绘图区域）
        CategoryPlot plot = (CategoryPlot) chart.getPlot();
        CategoryPlot plot2 = (CategoryPlot) chart2.getPlot();
        // 设置 X 轴字体
        CategoryAxis domainAxis = plot.getDomainAxis();
        CategoryAxis domainAxis2 = plot2.getDomainAxis();

        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90); // 90度竖排
        domainAxis.setLabelFont(labelFont); // X 轴标签字体
        domainAxis.setTickLabelFont(labelFont); // X 轴刻度字体

        domainAxis2.setCategoryLabelPositions(CategoryLabelPositions.UP_90); // 90度竖排
        domainAxis2.setLabelFont(labelFont); // X 轴标签字体
        domainAxis2.setTickLabelFont(labelFont); // X 轴刻度字体
        // 设置 Y 轴字体
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        NumberAxis rangeAxis2 = (NumberAxis) plot2.getRangeAxis();

        rangeAxis.setLabelFont(labelFont); // Y 轴标签字体
        rangeAxis.setTickLabelFont(labelFont); // Y 轴刻度字体
        rangeAxis.setTickUnit(new NumberTickUnit(50));
        chart.setBackgroundPaint(Color.WHITE); // 设置整个图表的背景颜色
        plot.setBackgroundPaint(new Color(255, 255, 255)); // 绘图区背景色（淡紫色）
        plot.setDomainGridlinePaint(Color.GRAY); // X 轴网格线颜色
        plot.setRangeGridlinePaint(Color.GRAY); // Y 轴网格线颜色


        rangeAxis2.setLabelFont(labelFont); // Y 轴标签字体
        rangeAxis2.setTickLabelFont(labelFont); // Y 轴刻度字体
        rangeAxis2.setTickUnit(new NumberTickUnit(50));
        chart2.setBackgroundPaint(Color.WHITE); // 设置整个图表的背景颜色
        plot2.setBackgroundPaint(new Color(255, 255, 255)); // 绘图区背景色（淡紫色）
        plot2.setDomainGridlinePaint(Color.GRAY); // X 轴网格线颜色
        plot2.setRangeGridlinePaint(Color.GRAY); // Y 轴网格线颜色

        // 获取图表渲染器
        LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();
        renderer.setSeriesPaint(0, Color.BLUE); // 修改折线颜色（红色）
        renderer.setSeriesStroke(0, new BasicStroke(3.0f)); // 线条加粗
        renderer.setSeriesPaint(1, Color.RED);   // 第二条线 (HbA1c)
        renderer.setSeriesStroke(1, new BasicStroke(3.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL, 0, new float[]{10, 5}, 0)); // 红色虚线
        // 设置数据标签
        renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        renderer.setDefaultItemLabelsVisible(true);

        // 获取图表渲染器
        LineAndShapeRenderer renderer2 = (LineAndShapeRenderer) plot2.getRenderer();
        renderer2.setSeriesPaint(0, Color.PINK); // 修改折线颜色（红色）
        renderer2.setSeriesStroke(0, new BasicStroke(3.0f)); // 线条加粗
        // 设置数据标签
        renderer2.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        renderer2.setDefaultItemLabelsVisible(true);


        // 设置数据标签的位置
        ItemLabelPosition position = new ItemLabelPosition(
                ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER
        );
        renderer.setDefaultPositiveItemLabelPosition(position);

        // 设置数据标签的位置
        ItemLabelPosition position2 = new ItemLabelPosition(
                ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER
        );
        renderer2.setDefaultPositiveItemLabelPosition(position2);

        // 将图表保存为图片
        byte[] chartImageBytes = null;
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            ChartUtils.writeChartAsPNG(baos, chart, 800, 600);
            chartImageBytes = baos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
// 将图表保存为图片
        byte[] chartImageBytes2 = null;
        try (ByteArrayOutputStream baos2 = new ByteArrayOutputStream()) {
            ChartUtils.writeChartAsPNG(baos2, chart2, 800, 600);
            chartImageBytes2 = baos2.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 将数据写入Excel并插入图表
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("湖北妇幼保健院用量统计表");
            CellStyle headerStyle = workbook.createCellStyle();
            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 设置前景色为黑色
            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充模式

            // 创建表头
            Row titleRow = sheet.createRow(0);

            Cell titleCell = titleRow.createCell(0);
            titleCell.setCellValue("湖北妇幼保健院");
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 3));
            CellStyle titleStyle = workbook.createCellStyle();
            titleStyle.setAlignment(HorizontalAlignment.CENTER);
            titleCell.setCellStyle(titleStyle);

            Row headerRow = sheet.createRow(1);
            headerRow.createCell(0).setCellStyle(headerStyle);
            headerRow.getCell(0).setCellValue("时间");
            headerRow.createCell(1).setCellStyle(headerStyle);
            headerRow.getCell(1).setCellValue("项目");
            headerRow.createCell(2).setCellStyle(headerStyle);
            headerRow.getCell(2).setCellValue("类型");
            headerRow.createCell(3).setCellStyle(headerStyle);
            headerRow.getCell(3).setCellValue("用量");


            // 填充数据
            int rowNum = 2;
            for (Map.Entry<String, Double> entry : monthlyUsage.entrySet()) {
                Row row = sheet.createRow(rowNum++);
                row.createCell(0).setCellValue(entry.getKey());
                row.createCell(1).setCellValue("FER");
                row.createCell(2).setCellValue("样本");
                row.createCell(3).setCellValue(entry.getValue());
            }
            int rowNum2 = 40;
            for (Map.Entry<String, Double> entry : monthlyUsage2.entrySet()) {
                Row row = sheet.createRow(rowNum2++);
                row.createCell(0).setCellValue(entry.getKey());
                row.createCell(1).setCellValue("POCT");
                row.createCell(2).setCellValue("样本");
                row.createCell(3).setCellValue(entry.getValue());
            }
            int rowNum3 = 80;
            for (Map.Entry<String, Double> entry : monthlyUsage3.entrySet()) {
                Row row = sheet.createRow(rowNum3++);
                row.createCell(0).setCellValue(entry.getKey());
                row.createCell(1).setCellValue("总计");
                row.createCell(2).setCellValue("样本");
                row.createCell(3).setCellValue(entry.getValue());
            }
            XSSFDrawing drawing = (XSSFDrawing) sheet.createDrawingPatriarch();

            // 插入图表到Excel
            if (chartImageBytes != null) {
                int pictureIdx = workbook.addPicture(chartImageBytes, Workbook.PICTURE_TYPE_PNG);

                XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 5, 0, 12, 26 );
                drawing.createPicture(anchor, pictureIdx);
            }
            // 插入图表到Excel
            if (chartImageBytes2 != null) {
                int pictureIdx = workbook.addPicture(chartImageBytes2, Workbook.PICTURE_TYPE_PNG);

                XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 12, 0, 19, 26 );
                drawing.createPicture(anchor, pictureIdx);
            }
            // 写入Excel文件
            try (FileOutputStream fileOut = new FileOutputStream("湖北妇幼保健院用量统计表.xlsx")) {
                workbook.write(fileOut);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
